<?php

namespace Api\Application;

use Api\Application;
use Api\Http\Exception\Exception404;
use Api\Http\Request;
use Api\Http\Response;
use Mobstar\Resource\Missions;
use Mobstar\Resource\Users;

/**
 * Class Bootstrap
 * @package Api\Application
 * @author Steffen Brem <steffenbrem@gmail.com>
 */
class Bootstrap
{
    /**
     * @var \Api\Application
     */
    protected $application;

    /**
     * @var \Api\Http\Request
     */
    protected $request;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->application = Application::$shared;

        if ($this->application->config['application']['mode'] == Application::MODE_STANDALONE)
        {
            $this->request = new Request();
        }
    }

    /**
     * @param Request $request
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;
    }

    /**
     * @return Request
     */
    public function getRequest()
    {
        return $this->request;
    }

    /**
     * @return mixed|Response
     * @throws \Api\Http\Exception\Exception404
     * @throws \Exception
     */
    public function dispatch()
    {
        // If we got no request object, stop dispatching
        if (!$this->request instanceof Request) return;

        // Call event
        $this->beforeDispatch();

        $class = $this->application->config['application']['namespace'] . '\Resource\\' . $this->request->getResource();

        if (!$this->request->getResource())
        {
            throw new Exception404("No resource specified.");
        }

        $obj = new $class($this->application);

        if (!is_callable(array($obj, $this->request->getRpc())))
        {
            throw new \Exception("Could not call RPC '" . $this->request->getRpc() . "' on resource '" . $class . "'.");
        }

        // Call resource RPC
        $r = call_user_func_array(array($obj, $this->request->getRpc()), array());

        // Call event
        $this->afterDispatch($r);

        return $r;
    }

    /**
     * Events
     */
    public function beforeDispatch() {}
    public function afterDispatch(&$response) {}
}